package com.bumptech.glide.provider;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.ArrayMap;

import com.bumptech.glide.util.MultiClassKey;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Maintains a cache of Model + Resource class to a set of registered resource classes that are
 * subclasses of the resource class that can be decoded from the model class.
 * <p>
 * 维护一个 Model + Resource 的缓存
 */
public class ModelToResourceClassCache {
    private final AtomicReference<MultiClassKey> resourceClassKeyRef = new AtomicReference<>();
    private final ArrayMap<MultiClassKey, List<Class<?>>> registeredResourceClassCache =
            new ArrayMap<>();

    @Nullable
    public List<Class<?>> get(
            @NonNull Class<?> modelClass,
            @NonNull Class<?> resourceClass,
            @NonNull Class<?> transcodeClass) {
        /**
         * 以原子方式设置为给定值，并返回旧值
         */
        MultiClassKey key = resourceClassKeyRef.getAndSet(null);
        if (key == null) {
            key = new MultiClassKey(modelClass, resourceClass, transcodeClass);
        } else {
            key.set(modelClass, resourceClass, transcodeClass);
        }
        final List<Class<?>> result;
        synchronized (registeredResourceClassCache) {
            result = registeredResourceClassCache.get(key);
        }
        resourceClassKeyRef.set(key);
        return result;
    }

    public void put(
            @NonNull Class<?> modelClass,
            @NonNull Class<?> resourceClass,
            @NonNull Class<?> transcodeClass,
            @NonNull List<Class<?>> resourceClasses) {
        synchronized (registeredResourceClassCache) {
            registeredResourceClassCache
                    .put(new MultiClassKey(modelClass, resourceClass, transcodeClass), resourceClasses);
        }
    }

    public void clear() {
        synchronized (registeredResourceClassCache) {
            registeredResourceClassCache.clear();
        }
    }
}
